home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / GC / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-25  |  7.3 KB  |  310 lines

  1. #define DEBUG       /* Some run-time consistency checks */
  2. #undef DEBUG
  3. #define VERBOSE
  4. #undef VERBOSE
  5.  
  6. #include <stdio.h>
  7. #include <signal.h>
  8. #include "gc.h"
  9.  
  10. int dont_gc = 0;
  11. extern long mem_found;
  12.  
  13. # ifdef MERGE_SIZES
  14. #   if MAXOBJSZ == MAXAOBJSZ
  15. #       define MAXSZ MAXOBJSZ
  16. #   else
  17.     --> causes problems here, since we cant map any size to a
  18.         size that doesnt have a free list.  Either initialization
  19.         needs to be cleverer, or we need separate maps for atomic
  20.         and composite objects.
  21. #   endif
  22.     long size_map[MAXSZ+1];
  23.  
  24.     /* Set things up so that size_map[i] >= i, but not too much bigger */
  25.     /* and so that size_map contains relatively few distinct entries   */
  26.     void init_size_map()
  27.     {
  28.     register int i;
  29.     register int i_rounded_up = 0;
  30.  
  31.     for (i = 1; i < 8; i++) {
  32. #           ifdef ALIGN_DOUBLE
  33.           size_map[i] = (i + 1) & (~1);
  34. #           else
  35.           size_map[i] = i;
  36. #           endif
  37.     }
  38.     for (i = 8; i <= MAXSZ; i++) {
  39.         if (i_rounded_up < i) {
  40. #               ifdef ALIGN_DOUBLE
  41.           i_rounded_up = (i + (i >> 1) + 1) & (~1);
  42. #               else                                       
  43.           i_rounded_up = i + (i >> 1);             
  44. #               endif
  45.         if (i_rounded_up > MAXSZ) {
  46.             i_rounded_up = MAXSZ;
  47.         }
  48.         }
  49.         size_map[i] = i_rounded_up;
  50.     }
  51.     }
  52. # endif
  53.  
  54.  
  55. /* allocate lb bytes of atomic data */
  56. struct obj * gc_malloc_atomic(lb)
  57. int lb;
  58. {
  59. register struct obj *op;
  60. register struct obj **opp;
  61. register int lw = BYTES_TO_WORDS(lb + (sizeof (word)) -1);
  62.  
  63. #   ifdef VERBOSE
  64.     printf("Here we are in gc_malloc_atomic(%d)\n",lw);
  65. #   endif
  66.     if( lw <= MAXAOBJSZ ) {
  67. #       ifdef MERGE_SIZES
  68.       lw = size_map[lw];
  69. #       endif
  70.     opp = &(aobjfreelist[lw]);
  71.         if( (op = *opp) == ((struct obj *)0) ) {
  72.         op = _allocaobj(lw);
  73.         }
  74. #       ifdef DEBUG
  75.         if ((op -> obj_link != ((struct obj *) 0)
  76.         && (((unsigned)(op -> obj_link)) > ((unsigned) HEAPLIM)
  77.            || ((unsigned)(op -> obj_link)) < ((unsigned) HEAPSTART)))) {
  78.         fprintf(stderr, "Bad free list in gc_malloc_atomic\n");
  79.         abort(op);
  80.             }
  81. #       endif
  82.         *opp = op->obj_link;
  83.         op->obj_link = (struct obj *)0;
  84.     } else {
  85.     register struct hblk * h;
  86.     if (!sufficient_hb(-lw) && !dont_gc) {
  87.             gcollect();
  88.     }
  89. #       ifdef VERBOSE
  90.         printf("gc_malloc_atomic calling allochblk(%x)\n",lw);
  91. #    endif
  92.     h = allochblk(-lw);
  93.     add_hblklist(h);
  94.     op = (struct obj *) (h -> hb_body);
  95.     }
  96.     return(op);
  97. }
  98.  
  99. /* allocate lb bytes of possibly composite data */
  100. struct obj * gc_malloc(lb)
  101. int lb;
  102. {
  103. register struct obj *op;
  104. register struct obj **opp;
  105. register int lw = BYTES_TO_WORDS(lb + (sizeof (word)) -1);
  106.  
  107.     if( lw <= MAXOBJSZ ) {
  108. #       ifdef MERGE_SIZES
  109.       lw = size_map[lw];
  110. #       endif
  111.     opp = &(objfreelist[lw]);
  112.         if( (op = *opp) == ((struct obj *)0) ) {
  113.         op = _allocobj(lw);
  114.         }
  115. #       ifdef DEBUG
  116.         if ((op -> obj_link != ((struct obj *) 0)
  117.         && (((unsigned)(op -> obj_link)) > ((unsigned) HEAPLIM)
  118.            || ((unsigned)(op -> obj_link)) < ((unsigned) HEAPSTART)))) {
  119.         fprintf(stderr, "Bad free list in gc_malloc\n");
  120.         abort(op);
  121.             }
  122. #       endif
  123.         *opp = op->obj_link;
  124.         op->obj_link = (struct obj *)0;
  125.     } else {
  126.     register struct hblk * h;
  127.  
  128.     if (!sufficient_hb(lw) && !dont_gc) {
  129.             gcollect();
  130.     }
  131. #       ifdef VERBOSE
  132.         printf("gc_malloc calling allochblk(%x)\n",lw);
  133. #    endif
  134.     h = allochblk(lw);
  135.     add_hblklist(h);
  136.     op = (struct obj *) (h -> hb_body);
  137.     }
  138.     return(op);
  139. }
  140.  
  141. void gc_free();
  142.  
  143. /* Change the size of the block pointed to by p to contain at least   */
  144. /* lb bytes.  The object may be (and quite likely will be) moved.     */
  145. /* The new object is assumed to be atomic if the original object was. */
  146. /* Shrinking of large blocks is not implemented well.                 */
  147. struct obj * gc_realloc(p,lb)
  148. struct obj * p;
  149. int lb;
  150. {
  151. register struct obj *op;
  152. register struct obj **opp;
  153. register struct hblk * h;
  154. register int sz;    /* Size of old object in bytes */
  155. int is_atomic;
  156.  
  157.     h = HBLKPTR(p);
  158.     sz = h -> hb_sz;
  159.     if (sz < 0) {
  160.     sz = -sz;
  161.     is_atomic = TRUE;
  162.     } else {
  163.     is_atomic = FALSE;
  164.     }
  165.     sz = WORDS_TO_BYTES(sz);
  166.  
  167.     if (is_atomic) {
  168.       if (sz > WORDS_TO_BYTES(MAXAOBJSZ)) {
  169.     /* Round it up to the next whole heap block */
  170.       sz = (sz+sizeof(struct hblkhdr)+HBLKSIZE-1)
  171.         & (~HBLKMASK);
  172.       sz -= sizeof(struct hblkhdr);
  173.       }
  174.       if (lb <= sz) {
  175.     if (lb >= (sz >> 1)) {
  176.         /* Already big enough, but not too much bigger than object. */
  177.         /* Ignore the request.                                      */
  178.         /* If sz is big enough, we should probably deallocate       */
  179.         /* part of the heap block here, but ...                     */
  180.         return(p);
  181.     } else {
  182.         /* shrink */
  183.           struct obj * result = gc_malloc_atomic(lb);
  184.  
  185.           bcopy(p, result, lb);
  186.           gc_free(p);
  187.           return(result);
  188.     }
  189.       } else {
  190.     /* grow */
  191.       struct obj * result = gc_malloc_atomic(lb);
  192.  
  193.       bcopy(p, result, sz);
  194.       gc_free(p);
  195.       return(result);
  196.       }
  197.     } else /* composite */ {
  198.       if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
  199.     /* Round it up to the next whole heap block */
  200.       sz = (sz+sizeof(struct hblkhdr)+HBLKSIZE-1)
  201.         & (~HBLKMASK);
  202.       sz -= sizeof(struct hblkhdr);
  203.       }
  204.       if (lb <= sz) {
  205.     if (lb >= (sz >> 1)) {
  206.         return(p);
  207.     } else {
  208.         /* shrink */
  209.           struct obj * result = gc_malloc(lb);
  210.  
  211.           bcopy(p, result, lb);
  212.           gc_free(p);
  213.           return(result);
  214.     }
  215.       } else {
  216.     /* grow */
  217.       struct obj * result = gc_malloc(lb);
  218.  
  219.       bcopy(p, result, sz);
  220.       gc_free(p);
  221.       return(result);
  222.       }
  223.     }
  224. }
  225.  
  226. /* Explicitly deallocate an object p */
  227. void gc_free(p)
  228. struct obj *p;
  229. {
  230.     register struct hblk *h;
  231.     register int sz;
  232.     register word * i;
  233.     register word * limit;
  234.  
  235.     h = HBLKPTR(p);
  236.     sz = h -> hb_sz;
  237.     if (sz < 0) {
  238.         sz = -sz;
  239.         if (sz > MAXAOBJSZ) {
  240.         h -> hb_uninit = 1;
  241.         del_hblklist(h);
  242.         freehblk(h);
  243.     } else {
  244.         p -> obj_link = aobjfreelist[sz];
  245.         aobjfreelist[sz] = p;
  246.     }
  247.     } else {
  248.     /* Clear the object, other than link field */
  249.         limit = &(p -> obj_component[sz]);
  250.         for (i = &(p -> obj_component[1]); i < limit; i++) {
  251.         *i = 0;
  252.         }
  253.     if (sz > MAXOBJSZ) {
  254.         p -> obj_link = 0;
  255.         h -> hb_uninit = 0;
  256.         del_hblklist(h);
  257.         freehblk(h);
  258.     } else {
  259.         p -> obj_link = objfreelist[sz];
  260.         objfreelist[sz] = p;
  261.     }
  262.     }
  263.     /* Add it to mem_found to prevent anomalous heap expansion */
  264.     /* in the event of repeated explicit frees of objects of   */
  265.     /* varying sizes.                                          */
  266.         mem_found += sz;
  267. }
  268.  
  269.  
  270. /*
  271.  * Disable non-urgent signals
  272.  */
  273. int holdsigs()
  274. {
  275.     unsigned mask = 0xffffffff;
  276.  
  277.     mask &= ~(1<<(SIGSEGV-1));
  278.     mask &= ~(1<<(SIGILL-1));
  279.     mask &= ~(1<<(SIGBUS-1));
  280.     mask &= ~(1<<(SIGIOT-1));
  281.     mask &= ~(1<<(SIGEMT-1));
  282.     mask &= ~(1<<(SIGTRAP-1));
  283.     mask &= ~(1<<(SIGQUIT-1));
  284.     return(sigsetmask(mask));
  285. }
  286.  
  287. void gc_init()
  288. {
  289.     word dummy;
  290. #   define STACKTOP_ALIGNMENT_M1 0xffffff
  291.  
  292.     heaplim = (char *) (sbrk(0));
  293. #   ifdef HBLK_MAP
  294.     heapstart = (char *) (HBLKPTR(((unsigned)sbrk(0))+HBLKSIZE-1 ));
  295. #   endif
  296. #   ifdef STACKTOP
  297.     stacktop = STACKTOP;
  298. #   else
  299.     stacktop = (word *)((((long)(&dummy)) + STACKTOP_ALIGNMENT_M1)
  300.                 & ~STACKTOP_ALIGNMENT_M1);
  301. #   endif
  302.     hincr = HINCR;
  303.     expand_hp(hincr);
  304.     init_hblklist();
  305. #   ifdef MERGE_SIZES
  306.       init_size_map();
  307. #   endif
  308. }
  309.  
  310.